/// <reference path="../../index.d.ts" />

"use strict"
const Controller = require("egg").Controller
const {sendStat, genRandomStr} = require("../extend/helper")
const fs = require("fs")
const path = require("path")

class ApplicationController extends Controller {
	constructor(ctx) {
		super(ctx)
		this.Application = this.app.model.Application
		this.imgBase = this.config.serverConfig.imgBase
		this.uploadPath = this.app.config.serverConfig.uploadPath
	}

	async list() {
		let type = Number(this.ctx.query.type)
		if (type !== 1 && type !== 2) {
			this.ctx.body = sendStat(this.config.constant.ERROR_METHOD_NOT_ALLOWED)
			this.ctx.status = 422
		}
		//1为小程序,2 为公众号
		let data = await this.Application.findAll(
			{
				attributes: ["create_at", "app_type", "applicat_name", "head_url", "id"],
				where: {
					app_type: type == 1 ? {$lte: 2} : {$gt: 2}
				}
			}
		)
		this.ctx.body = sendStat(this.config.constant.NORMAL, data)
	}

	async findById() {
		this.ctx.validate({aid: "id"}, this.ctx.query)
		let data = await this.Application.findOne({
			where: {
				id: this.ctx.query.aid
			}
		})
		this.ctx.body = sendStat(this.config.constant.NORMAL, data)
	}

	async create() {

		let {ctx, config, app} = this
		let body = Object.assign({}, ctx.req.body)

		// 校验
		ctx.validate({app_type: "numstr", applicat_name: "string", app_id: "string", app_secret: "string", base_id: "string"}, body)
		if (!Array.isArray(ctx.req.files)) {
			ctx.throw(422, "no has file", {
				code: "invalid_param",
				errors: [{"message": "required", "field": "head", "code": "missing_file"}],
			})
		}

		let d = await app.model.transaction(async (params) => {
			var {app_type, applicat_name, app_id, app_secret, base_id} = body
			let token = "wechat_2041"
			let encoding_aeskey = genRandomStr(43)
			let createStat = await this.Application.create({app_type, applicat_name, app_id, app_secret, token, encoding_aeskey, base_id})
			if (!createStat) {// 初始化创建
				ctx.body = sendStat(config.constant.ERROR_SQL_CREATE)
				await params.rollback()
			} else {
				let server_url = config.serverConfig.host + "wechat/auth?aid=" + createStat.id
				createStat.server_url = server_url
				await createStat.save()
				let fileObj = {}
				ctx.req.files.forEach((val) => {
					fileObj[val.fieldname] = val
				})
				if (fileObj.head == undefined || fileObj.qrcode == undefined) {
					await params.rollback()
					ctx.body = sendStat(config.constant.ERROR_PARAM_UPLOAD_MISS)
				} else {
					let headFileName = fileObj.head.filename + "." + fileObj.head.mimetype.split("/").pop()
					let mvHeadPath = path.resolve(this.uploadPath, headFileName)
					fs.renameSync(fileObj.head.path, mvHeadPath)
					// 头像
					let qrcodeFileName = fileObj.qrcode.filename + "." + fileObj.qrcode.mimetype.split("/").pop()
					let mvQrCodePath = path.resolve(path.join(this.uploadPath, qrcodeFileName))
					fs.renameSync(fileObj.qrcode.path, mvQrCodePath)

					let updateStat = await this.Application.update({head_url: this.imgBase + headFileName, qrcode_url: this.imgBase + qrcodeFileName}, {
						where: {
							id: createStat.id
						}
					})
					ctx.body = sendStat(config.constant.NORMAL, {id: createStat.id, updateStat})
				}
			}
		})
		this.app.cache.application = undefined
		return d
	}

	/**
   * 
   * @param {import("egg").Context} ctx 
   * @param {Function} next 
   */
	async updateKey(ctx) {

		let queryObj = this.ctx.request.body
		this.ctx.validate({key: ["applicat_name", "qr_scene_str", "app_id", "base_id", "app_type", "app_secret", "server_url", "token", "encoding_aeskey", "account_id", "version"], val: "string", aid: "id"}, queryObj)
		switch (queryObj.key) {
		case "app_id":
			ctx.validate({val: "alphanum"}, queryObj)
			break
		case "account_id":
			ctx.validate({val: "id"}, queryObj)
			break
		case "app_type":
			ctx.validate({val: "intstr"}, queryObj)
		}
		let updateStat = await this.Application.update({
			[queryObj.key]: queryObj.val
		}, {
			where: {
				id: queryObj.aid
			}
		})
		ctx.body = sendStat(this.config.constant.NORMAL, "you update:" + JSON.stringify({
			[queryObj.key]: queryObj.value
		}))
		this.app.cache.application = undefined
	}

	async updateImg() {
		let {ctx, config, app} = this
		let body = Object.assign({}, ctx.req.body)
		ctx.validate({aid: "numstr"}, body)
		let fileObj = {}
		ctx.req.files.forEach((val) => {
			fileObj[val.fieldname] = val
		})
		let keyMap = {
			head: "head_url", qrcode: "qrcode_url"
		}
		if (!Array.isArray(ctx.req.files) || ctx.req.files.length == 0 || ctx.req.files.length > 1 || (fileObj.head == undefined && fileObj.qrcode == undefined)) {
			ctx.throw(422, "no has file", {
				code: "invalid_param",
				errors: [{"message": "required", "field": "head", "code": "missing_file"}],
			})
		}
		let key = ctx.req.files[0].fieldname
		let fileName = fileObj[key].filename + "." + fileObj[key].mimetype.split("/").pop()
		let mvHeadPath = path.resolve(path.join(this.uploadPath, fileName))

		fs.renameSync(fileObj[key].path, mvHeadPath)

		await this.Application.update({[keyMap[key]]: this.imgBase + fileName}, {
			where: {
				id: body.aid
			}
		})
		ctx.body = sendStat(config.constant.NORMAL, "创建成功")
		this.app.cache.application = undefined
	}
}

module.exports = ApplicationController
